#include "MissileObject.h"
#include "Actor.h"
#include "GameGUI.h"
#include "GameApp.h"

//-------------------------------------------------------------------------------------
MissileObject::MissileObject(std::string id)
	: BaseObject(id), mSync(false), mParticle(0), mLoadedParticle(false)
{
	boost::shared_ptr<SettingsManager> sm(new SettingsManager(id));
	readBaseObjectFromXML(sm);

	mpOgreInitData->pos = Ogre::Vector3();

	mBasis = btMatrix3x3::getIdentity();
	mDirection = btVector3();
	mPower = 0.0f;
}
//-------------------------------------------------------------------------------------
MissileObject::MissileObject(boost::shared_ptr<MissileObject> ref, const float x, const float y, const float z, btMatrix3x3 &basis, btVector3 &direction)
	: BaseObject(ref), mSync(false), mParticle(0), mLoadedParticle(false)
{
	mSpeed = ref->getSpeed();
	mLifeTime = ref->getLifeTime();
	mpOgreInitData->pos = Ogre::Vector3(x, y, z);
	mBasis = basis;
	mDirection = direction;
	mDirection.normalize();
	mPower = 0.0f;
}
//-------------------------------------------------------------------------------------
MissileObject::~MissileObject(void)
{
}
//-------------------------------------------------------------------------------------
void MissileObject::collision(BaseObjectPtr obj, btVector3 &point)
{
	if (!mbDead)
	{
	if(obj->hasType(OBJECT_ENEMY) && !dead())
	{

		ActorPtr actor = boost::static_pointer_cast<Actor>(obj);
		
		/*btVector3 enemyPos = actor->getBody()->getWorldTransform().getOrigin();
		btVector3 myPos = mpBody->getWorldTransform().getOrigin();

		btVector3 dir = enemyPos - myPos;
		actor->knockBack(dir.normalized() * (power/2));*/

		actor->recieveDmg(this->getBody()->getWorldTransform().getOrigin(), mPower);
		gpApp->mpGameLogic->createParticleSystem(Ogre::String("Blood1"), 1000, cvt(point));
	}
	kill();
	}
}
//-------------------------------------------------------------------------------------
void MissileObject::setPower(float power)
{
	mPower = power;
}
//-------------------------------------------------------------------------------------
ObjectType MissileObject::getType(void) const
{
	return OBJECT_MISSILE;
}
//-------------------------------------------------------------------------------------
void MissileObject::update(const unsigned long elapsedTime)
{
	// Initialize direction and velocity of the missile
	if (!mSync)
	{
		btTransform &trans = mpBody->getWorldTransform();
		btVector3 pos = cvt(mpOgreInitData->pos) + 0.5f * mDirection;
		trans.setOrigin(pos);
		trans.setBasis(mBasis);

		mDirection *= mSpeed;
		mpBody->setLinearVelocity(mDirection);

		if (mLoadedParticle) mParticle = gpApp->mpGameLogic->createParticleSystem("FlameMissile2", cvt(pos));
		else mParticle = gpApp->mpGameLogic->createParticleSystem("FlameMissile", cvt(pos));

		mpBody->activate();
		mSync = true;
	}

	mParticle->setPosition(cvt(mpBody->getWorldTransform().getOrigin()));
	mpBody->setLinearVelocity(mDirection);

	// Decrease life time of the missile
	if (elapsedTime >= mLifeTime)
	{
		kill();
		return;
	}

	mLifeTime -= elapsedTime;
}
//-------------------------------------------------------------------------------------
void MissileObject::readBaseObjectFromXML(boost::shared_ptr<SettingsManager> sm)
{
	mSpeed = (float)atof(sm->getSetting("MissileData/Speed").c_str());
	mLifeTime = atoi(sm->getSetting("MissileData/LifeTime").c_str());
}
//-------------------------------------------------------------------------------------
float MissileObject::getSpeed() const
{
	return mSpeed;
}
//-------------------------------------------------------------------------------------
unsigned long MissileObject::getLifeTime() const
{
	return mLifeTime;
}
//-------------------------------------------------------------------------------------
void MissileObject::kill(void)
{
	if (mLoadedParticle) gpApp->mpGameLogic->createParticleSystem(Ogre::String("Explosion2"), 500, cvt(mpBody->getWorldTransform().getOrigin()));
	else gpApp->mpGameLogic->createParticleSystem(Ogre::String("Explosion"), 500, cvt(mpBody->getWorldTransform().getOrigin()));

	if (mParticle) gpApp->mpView->getSceneManager()->getRootSceneNode()->removeAndDestroyChild(mParticle->getName());
	mParticle = 0;

	if (mpBody) gpApp->mpGameLogic->getPhysics()->removeBody(mpBody);
	mpBody = 0;
	
	if(!mbDead)mpAnimator->resetAnimations();
	if (mpNode) gpApp->mpView->removeObject(mpNode);
	mpNode = 0;
	mpEntityNode = 0;

	mbDead = true;
}
//-------------------------------------------------------------------------------------
void MissileObject::setLoadedParticle(const bool loaded)
{
	mLoadedParticle = loaded;
}